package main

import (
	"fmt"
)

type EleState uint8

const (
	Idle EleState = iota + 1
	Uping
	Downing
	Malfunction
)

const (
	MinFloor = -3
	MaxFloor = 24
	MalCount = 100
)

type Elevator struct {
	CurFloor int
	Count    int
	State    EleState
}

func main() {
	e := &Elevator{
		CurFloor: 1,
		Count:    0,
		State:    Idle,
	}
	for {
		fmt.Printf("输入%d - %d之间要去的楼层: ", MinFloor, MaxFloor)
		var dstFloor int
		if _, err := fmt.Scanf("%d", &dstFloor); err != nil {
			fmt.Printf("请输入%d - %d的楼层号\n", MinFloor, MaxFloor)
			continue
		}
		if dstFloor < MinFloor || dstFloor > MaxFloor {
			fmt.Printf("请输入%d - %d的楼层号\n", MinFloor, MaxFloor)
			continue
		}
		if dstFloor == 0 {
			fmt.Println("没有0层，自动设置为1层")
			dstFloor = 1
		}
		e.Run(dstFloor)
	}
}

func (e *Elevator) Run(dstFloor int) {
	for {
		if e.CurFloor == dstFloor {
			if e.Count > MalCount {
				e.Malf()
				return
			}
			e.Halt()
			return
		}
		switch e.State {
		case Idle:
			if e.CurFloor < dstFloor {
				e.GoUp()
			}
			if e.CurFloor > dstFloor {
				e.GoDown()
			}
		case Uping:
			if e.CurFloor < dstFloor {
				e.GoUp()
			}
		case Downing:
			if e.CurFloor > dstFloor {
				e.GoDown()
			}
		case Malfunction:
			e.Malf()
			return
		}
	}
}

func (e *Elevator) Halt() {
	e.State = Idle
	fmt.Printf("at Floor %d\n", e.CurFloor)
}

func (e *Elevator) GoUp() {
	e.CurFloor++
	if e.CurFloor == 0 {
		e.CurFloor++
	}
	e.State = Uping
	fmt.Printf("up Floor %d\n", e.CurFloor)
	e.Count++
}

func (e *Elevator) GoDown() {
	e.CurFloor--
	if e.CurFloor == 0 {
		e.CurFloor--
	}
	e.State = Downing
	fmt.Printf("down Floor %d\n", e.CurFloor)
	e.Count++
}

func (e *Elevator) Malf() {
	e.State = Malfunction
	fmt.Println("elevator malfuction")
}
